/*
 * @Author: shawnxiao
 * @Date: 2021-10-15 16:33:08
 * @LastEditTime: 2021-11-19 10:38:56
 * @FilePath: /gatt-react/src/index/views/Home/components/GattDrag/components/GattTree/index.tsx
 */
import React, {useState, useRef, useEffect} from 'react'
import { Table, Popover, Divider, List, Modal } from 'antd'
import useDeepCompareEffect from '@/common/utils/useDeepCompareEffect'
import DynamicFormReader from '@/components/DynamicFormReader'
import ModelCustom from '@/index/components/ModelCustom'
import {formatToTree} from '@/common/utils'
import { SettingOutlined, MoreOutlined } from '@ant-design/icons'
import InfiniteScroll from 'react-infinite-scroll-component'
import './index.less'
interface propsType{
  fieldsAttr:any
  setDataArr:any
  setFieldsAttr:any
  dataArr:any[]
}

function GattTree(props:propsType) {
  const {dataArr, setDataArr, fieldsAttr, setFieldsAttr} = props
  const [columns, setColumns] = useState<any[]>([])
  const [tableData, setTableData] = useState<any[]>([])
  const [expandedRowKeys, setExpandedRowKeys] = useState<any[]>([])
  const [deleteIds, setDeleteIds] = useState<any[]>([]) // 暂存删除的id
  const [scroll, setScroll] = useState<any>({})
  const boxRef = useRef<any>(null)

  // 设置表格显示列字段下的表单动态渲染
  const SetTableHeadContent = (propsSetTableHeadContent:any) => {
    const {setVisiblePopover} = propsSetTableHeadContent
    const [configs, setConfigs] = useState<any[]>([])
    const childRef:any = useRef()
  // const onTest = () => {
  //   // 在组件外部重置表单的值
  //   const form = childRef.current.getForm()
  //   console.log(form, form.getFieldsValue())
  //   // form.resetFields()
  // }
    const finishToSave = (form:any) => {
      const res:any = JSON.parse(JSON.stringify(fieldsAttr))
      Object.keys(res).forEach((key:string) => {
        res[key].showTable = form[key]
      })
      setFieldsAttr({...res})
      setVisiblePopover(false)
    }

    useDeepCompareEffect(() => {
      const configs:any[] = [
        {
          'type': 'basic',
          'title': '不显示类型',
          'dataIndex': 1,
          'noCollapse': true,
          'gutter': [10, 10],
          'list': []
        }
      ]
      Object.keys(fieldsAttr).map((key:string, index:number) => {
        configs[0].list.push({
          'rules': [{'required': false, 'message': '此为必填项!'}],
          key,
          'title': fieldsAttr[key]?.label,
          'type': 'switch',
          'checkedChildren': '显示',
          'unCheckedChildren': '隐藏',
          'valuePropName': 'checked',
          'value': fieldsAttr[key]?.showTable,
          'disabled': key?.includes('name'),
          'colSpan': 24,
          'labelCol': {'span': 12, 'offset': 0},
          'wrapperCol': {'span': 12, 'offset': 0},
          'dataIndex': index
        })
      })
      setConfigs(configs)
    }, [fieldsAttr])

    return (
      <div
        id="scrollAbleDiv"
        className="scrollAbleDiv"
      >
        <InfiniteScroll
          dataLength={configs.length}
          next={() => {}}
          hasMore={configs.length < 50}
          loader={null}
          endMessage={<Divider plain>没有更多了！</Divider>}
          scrollableTarget="scrollAbleDiv"
        >
          <DynamicFormReader
            configs={configs} formData={{}}
            cRef={childRef} noAction={false}
            layout="horizontal"
            btnTxt="确定"
            btnSize="small"
            styleCollapse={{'backgroundColor': '#fff', border: 'none'}}
            finishToSave={finishToSave}
            spaceProps={{align: 'center', direction: 'horizontal'}}
          />
          {/* <Button onClick={onTest} size="small">父级获取子的表单值</Button> */}
        </InfiniteScroll>
    </div>
    )
  }
  // 设置表格显示列字段
  const SetTableHead = () => {
    const [visiblePopover, setVisiblePopover] = useState(false)
    const handleVisibleChange = (visible:boolean) => {
      setVisiblePopover(visible)
    }
    return (
    <Popover
      content={<SetTableHeadContent setVisiblePopover={setVisiblePopover}/>}
      title="设置表头显示的内容"
      trigger="click"
      visible={visiblePopover}
      onVisibleChange={handleVisibleChange}
      >
      <span
        onClick={e => e.preventDefault()}
        style={{display: 'inline-block', width: '100%', textAlign: 'center', fontSize: '14px', cursor: 'pointer'}}>
          <SettingOutlined />
      </span>
  </Popover>
  )
  }
  // 编辑行菜单列表
  const EditTableRowAction = (props:any) => {
    // eslint-disable-next-line react/prop-types
    const {data, setVisiblePopover} = props
    const typeArr1 = [{label: '编辑', action: 'edit'}, {label: '删除', action: 'delete', title: '此操作将永久删除该项目, 是否继续?'}, {label: '计划项目', value: 2, action: 'transform'}] // 里程碑
    const typeArr2 = [{label: '编辑', action: 'edit'}, {label: '删除', action: 'delete', title: '此操作将永久删除该项目, 是否继续?'}, {label: '分组', value: 3, action: 'transform'}, {label: '里程碑', value: 1, action: 'transform'}] // 计划项目
    const typeArr3 = [{label: '编辑', action: 'edit'}, {label: '删除分组', action: 'delete', title: '此操作将永久删除该分组及其子项目, 是否继续?'}, {label: '添加任务', action: 'add'}] // 分组
    // eslint-disable-next-line react/prop-types
    const list = ~~data?.type === 1 ? [...typeArr1] : ~~data?.type === 2 ? [...typeArr2] : [...typeArr3]
    const handleClick = (params:any) => {
      const {item, data} = params
      const {action} = item
      if (action.includes('add')){
        // 新增
      }
      if (action.includes('delete')){
        // 删除
        const config = {
          title: '提示',
          content: (<h4>{item?.title}</h4>),
          onOk(close:() => void) {
            const ids:string | number[] = [data.id]
            if (data?.children?.length){
              const loop = (arr:any[]) => {
                arr.forEach((item:any) => {
                  ids.push(item.id)
                  if (item?.children?.length){
                    loop(item.children)
                  }
                })
              }
              loop(data.children)
            }
            setDeleteIds([...ids])
            close && close()
            setVisiblePopover(false)
          }
        }
        Modal.confirm(config)
      }
      if (action.includes('edit')){
        console.log(data)
        // 编辑
        const config = {
          title: '编辑',
          className: '',
          vNode: (<h4>{item?.title}</h4>),
          callback: () => {
            setVisiblePopover(false)
          }
        }
        ModelCustom(config)
      }
    }
    return (
      <List
        dataSource={list}
        size="small"
        renderItem={item => <List.Item onClick={handleClick.bind(null, {item, data})} style={{padding: '5px 0', justifyContent: 'center', cursor: 'pointer'}}>{item?.label}</List.Item>}
      >
      </List>
    )
  }
  // 编辑行
  const EditTableRow = (props:any) => {
    const {data} = props
    const [visiblePopover, setVisiblePopover] = useState(false)
    const handleVisibleChange = (visible:boolean) => {
      setVisiblePopover(visible)
    }
    return (
    <Popover
      content={<EditTableRowAction data={data} setVisiblePopover={setVisiblePopover}/>}
      title=""
      trigger="click"
      placement="topRight"
      visible={visiblePopover}
      onVisibleChange={handleVisibleChange}
      >
      <span
        onClick={e => e.preventDefault()}
        style={{display: 'inline-block', width: '100%', textAlign: 'center', fontSize: '14px', transform: 'scale(1.5)', cursor: 'pointer'}}>
        <MoreOutlined rotate={180}/>
      </span>
  </Popover>
  )
  }

  useDeepCompareEffect(() => {
    const arr:any[] = []
    for (const key in fieldsAttr) {
      if (fieldsAttr[key]?.showTable){
        const obj = {
          title: fieldsAttr[key].label,
          dataIndex: key,
          width: key.includes('name') ? '220px' : '150px',
          key
        }
        arr.push(obj)
      }
    }
    arr.push({
      title: <SetTableHead/>,
      key: 'action',
      width: 40,
      render: (row:any, record:any) => (
        <EditTableRow key={record?.id} data={row}/>
      )
    })
    setColumns([...arr])
  }, [fieldsAttr])

  useDeepCompareEffect(() => {
    const arr = JSON.parse(JSON.stringify(dataArr))
    const tree = formatToTree([...arr])
    setTableData(tree)
    const expandRowKeys:any[] = []
    dataArr.forEach((i:any) => {
      if (i.expand){
        expandRowKeys.push(i.id)
      }
    })
    setExpandedRowKeys([...expandRowKeys])
  }, [dataArr])

  const onExpand = (expanded:boolean, record:any) => {
    const ids:any[] = [{pid: record.id}]
    if (record?.children?.length){
      const loop = (arr:any[]) => {
        arr.forEach((item:any) => {
          ids.push({id: item.id})
          if (item?.children?.length){
            loop(item.children)
          }
        })
      }
      loop(record.children)
    }
    dataArr.map((item:any) => {
      ids.forEach((i:any) => {
        if (item.id === i.id){
          item.expand = expanded
          item.isShow = expanded
        }
        if (item.id === i.pid){
          item.expand = expanded
        }
      })
    })
    setDataArr([...dataArr])
  }
  const handleScroll = (scrollBody:any) => {
    const scrollTopTmp = scrollBody.scrollTop
    const r = document.getElementById('gatt-box-root-right')
    if (r){
      const c = r.querySelector('.gatt-main-wrap-cont')
      if (c){
        c.scrollTop = scrollTopTmp
      }
    }
  }

  useEffect(() => {
    const y = boxRef.current.clientHeight - 41
    const obj:any = {}
    if (y < dataArr.filter((item:any) => item?.isShow).length * 40){
      obj.y = y
    }
    setScroll({...obj})
    setTimeout(() => {
      const scrollBody = boxRef.current.querySelector('.ant-table-body')
      if (scrollBody){
        scrollBody.addEventListener('scroll', handleScroll.bind(null, scrollBody))
      }
      return () => {
        if (scrollBody){
          scrollBody.removeEventListener('scroll', handleScroll.bind(null, scrollBody))
        }
      }
    }, 0)
  }, [])

  // 监听删除id
  useDeepCompareEffect(() => {
    if (deleteIds.length){
      const filterDataArr = dataArr.filter((item:any) => !(deleteIds.includes(item.id)))
      setDataArr([...filterDataArr])
    }
  }, [deleteIds])

  return (
    <div
      className="tree-table-box"
      id="treeTableBox"
      style={{overflow: scroll?.y ? 'auto' : 'scroll'}}
      ref={boxRef}>
      <Table
        rowKey={((record:any) => record.id)}
        scroll={scroll}
        size='small'
        expandable={
          {
            expandedRowKeys,
            onExpand,
            rowExpandable: record => record.expand ? true : false // 全部开启展开属性
          }
        } // //初始时展开所有行
        pagination={false}
        columns={columns}
        dataSource={tableData}
      />
    </div>
  )
}

export default GattTree
